package cool.webstudy.admin.service.impl;

import cool.webstudy.admin.constant.enums.CompetitionStatusEnum;
import cool.webstudy.admin.constant.enums.ConfigTypeEnum;
import cool.webstudy.admin.constant.enums.rescode.AuthResCodeEnum;
import cool.webstudy.admin.constant.enums.rescode.DynamicFlagResCodeEnum;
import cool.webstudy.admin.constant.enums.rescode.CompetitionResCodeEnum;
import cool.webstudy.admin.constant.enums.rescode.TeamUserResCodeEnum;
import cool.webstudy.admin.exception.BusinessException;
import cool.webstudy.admin.model.dto.attackrecord.CreateAttackRecordDTO;
import cool.webstudy.admin.model.dto.competition.QueryCompetitionDetailInfoDTO;
import cool.webstudy.admin.model.dto.competition.team.QueryCompTeamDetailInfoDTO;
import cool.webstudy.admin.model.dto.competition.team.UpdateCompetitionTeamFlagDTO;
import cool.webstudy.admin.model.dto.flag.CommitFlagDTO;
import cool.webstudy.admin.model.dto.team.user.TeamUserDetailInfoDTO;
import cool.webstudy.admin.model.dto.user.UserDetailInfoDTO;
import cool.webstudy.admin.service.*;
import cool.webstudy.admin.service.docker.ContainerService;
import cool.webstudy.admin.utils.UserDetailUtil;
import cool.webstudy.common.utils.UUIDUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author 莫振双
 * @date 2025/3/15 10:38
 * @description: 动态flag服务实现类
 */
@Service
public class DynamicFlagServiceImpl implements DynamicFlagService {
    @Autowired
    private CompetitionService competitionService;
    @Autowired
    private CompetitionTeamService competitionTeamService;
    @Autowired
    private ConfigService configService;
    @Autowired
    private ContainerService containerService;
    @Autowired
    private TeamUserService teamUserService;
    @Autowired
    private AttackRecordService attackRecordService;
    @Autowired
    private ICheckService checkService;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchRefreshFlag(String competitionUnCode) {
        if (StringUtils.isBlank(competitionUnCode)){
            throw new BusinessException(DynamicFlagResCodeEnum.RC_ERROR_COMPETITION_UN_CODE_MISS);
        }
        //判断当前赛事是否正在进行
        QueryCompetitionDetailInfoDTO competitionDetailInfo = competitionService.queryCompetitionDetailInfo(competitionUnCode);
        if (Objects.isNull(competitionDetailInfo)){
            throw new BusinessException(CompetitionResCodeEnum.RC_COMPETITION_NOT_EXIST);
        }
        if (competitionDetailInfo.getStatusFlag() != CompetitionStatusEnum.IN_THE_COMP){
            throw new BusinessException(CompetitionResCodeEnum.RC_ERROR_NOT_IN_THE_COMP);
        }
        //获取赛事队伍列表
        List<QueryCompTeamDetailInfoDTO> teamList = competitionTeamService.queryCompTeamDetailInfoList(competitionUnCode);
        if (Objects.isNull(teamList) || teamList.isEmpty()){
            throw new BusinessException(DynamicFlagResCodeEnum.RC_ERROR_TEAM_COUNT_IS_ZERO);
        }
        //批量检查队伍站点状况
        checkService.checkDown(teamList);
        //获取动态flag前缀配置信息
        String dynamicFlagPrefix = configService.queryConfig(ConfigTypeEnum.DYNAMIC_FLAG_PREFIX_CONFIG);
        //容器id和flag信息map
        Map<String, String> containerIdAndFlagMap = new HashMap<>();
        List<UpdateCompetitionTeamFlagDTO> updateCompetitionTeamFlagDTOList = getUpdateCompetitionTeamFlagDTOList(teamList, dynamicFlagPrefix,containerIdAndFlagMap);
        //批量更新flag
        //更新数据库中队伍flag信息
        competitionTeamService.batchUpdateCompetitionTeamFlag(updateCompetitionTeamFlagDTOList);
        //批量更新容器flag信息
        containerService.batchRefreshFlag(containerIdAndFlagMap);
    }

    private List<UpdateCompetitionTeamFlagDTO> getUpdateCompetitionTeamFlagDTOList(List<QueryCompTeamDetailInfoDTO> teamList, String dynamicFlagPrefix, Map<String, String> containerIdAndFlagMap) {
        List<UpdateCompetitionTeamFlagDTO> updateCompetitionTeamFlagDTOList = new ArrayList<>();
        for (QueryCompTeamDetailInfoDTO team : teamList) {
            UpdateCompetitionTeamFlagDTO updateCompetitionTeamFlagDTO = new UpdateCompetitionTeamFlagDTO();
            updateCompetitionTeamFlagDTO.setUnCode(team.getUnCode());
            String flag = String.format(dynamicFlagPrefix, UUIDUtil.getUUID());
            String containerId = team.getContainerId();
            updateCompetitionTeamFlagDTO.setFlag(flag);
            updateCompetitionTeamFlagDTOList.add(updateCompetitionTeamFlagDTO);
            containerIdAndFlagMap.put(containerId, flag);
        }
        return updateCompetitionTeamFlagDTOList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void refreshFlag(String competitionUnCode, String containerId) {

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteFlag(String competitionUnCode) {

    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void commitFlag(CommitFlagDTO dto) {
        if (StringUtils.isBlank(dto.getFlag())){
            throw new BusinessException(DynamicFlagResCodeEnum.RC_ERROR_FLAG_MISS);
        }
        String flag = dto.getFlag();
        //获取该flag所属比赛队伍信息
        QueryCompTeamDetailInfoDTO compTeamDetailInfo = competitionTeamService.queryCompTeamDetailInfoByFlag(flag);
        if (Objects.isNull(compTeamDetailInfo)){
            throw new BusinessException(DynamicFlagResCodeEnum.RC_ERROR_FLAG_VALIDATION_FAILED);
        }
        //查询当前登录用户所属队伍的队伍信息
        UserDetailInfoDTO userDetailInfoDTO = UserDetailUtil.getUserDetailInfo();
        if (userDetailInfoDTO.getAccount().equals("system")){
            throw new BusinessException(AuthResCodeEnum.RC_NOT_FOUND_TOKEN);
        }
        TeamUserDetailInfoDTO teamUserDetailInfoDTO = teamUserService.queryTeamUserDetailInfoDTOByUserUnCode(userDetailInfoDTO.getUnCode());
        if (Objects.isNull(teamUserDetailInfoDTO)){
            throw new BusinessException(TeamUserResCodeEnum.RC_ERROR_NOT_IN_TEAM);
        }
        //判断是否是自己队伍的flag
        if (teamUserDetailInfoDTO.getTeamUnCode().equals(compTeamDetailInfo.getTeamUnCode())){
            throw new BusinessException(DynamicFlagResCodeEnum.RC_ERROR_COMMIT_SELF_TEAM_FLAG);
        }
        //判断flag是否存在
        if (attackRecordService.isExistRecord(compTeamDetailInfo.getCompUnCode(), teamUserDetailInfoDTO.getTeamUnCode(),flag)){
            throw new BusinessException(DynamicFlagResCodeEnum.RC_ERROR_FLAG_COMMITTED);
        }
        //查询赛事信息，判断赛事状态，获取赛事每次攻击分数值
        QueryCompetitionDetailInfoDTO competitionDetailInfo = competitionService.queryCompetitionDetailInfo(compTeamDetailInfo.getCompUnCode());
        if (competitionDetailInfo.getStatusFlag() != CompetitionStatusEnum.IN_THE_COMP){
            throw new BusinessException(CompetitionResCodeEnum.RC_ERROR_NOT_IN_THE_COMP);
        }
        Integer scorePerAttack = competitionDetailInfo.getScorePerAttack();
        //更新队伍分数
        Integer attackerTeamScore;
        Integer teamUnUnderAttackScore;
        teamUnUnderAttackScore = competitionTeamService.updateCompTeamScore(competitionDetailInfo.getUnCode(),compTeamDetailInfo.getTeamUnCode(),scorePerAttack,false);
        attackerTeamScore = competitionTeamService.updateCompTeamScore(competitionDetailInfo.getUnCode(),teamUserDetailInfoDTO.getTeamUnCode(),scorePerAttack,true);
        //插入攻击记录
        CreateAttackRecordDTO createAttackRecordDTO = new CreateAttackRecordDTO();
        createAttackRecordDTO.setCompUnCode(compTeamDetailInfo.getCompUnCode());
        createAttackRecordDTO.setAttackerTeamUnCode(teamUserDetailInfoDTO.getTeamUnCode());
        createAttackRecordDTO.setAttackerTeamScore(attackerTeamScore);
        createAttackRecordDTO.setTeamUnCodeUnderAttack(compTeamDetailInfo.getTeamUnCode());
        createAttackRecordDTO.setTeamUnUnderAttackScore(teamUnUnderAttackScore);
        createAttackRecordDTO.setFlag(flag);
        createAttackRecordDTO.setScores(scorePerAttack);
        attackRecordService.createAttackRecord(createAttackRecordDTO);
    }
}
